package com.itbaizhan.publish;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
/*RabbitMQ发布订阅模式*/
//生产者
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory =new ConnectionFactory();
        connectionFactory.setHost("192.168.66.101");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("itbaizhan");
        connectionFactory.setPassword("itbaizhan");
        connectionFactory.setVirtualHost("/"); //设置虚拟机，默认是 /
        //创建连接
        Connection connection = connectionFactory.newConnection();
        //建立信道
        Channel channel = connection.createChannel();
        //创建交换机  declare :声明; 宣布; 宣告; 宣称
        /*
        * 参数1：交换机名
        * 参数2：交换机类型
        * 参数3：交换机持久化*/
        channel.exchangeDeclare("exchange_fanout", BuiltinExchangeType.FANOUT,true);

        //创建队列
        /*
         *参数1：队列名
         * 参数2：是否持久化，true表示MQ重启后队列还在
         * 参数3：是否私有化，false表示所有消费者都可以访问  true表示只有第一次拥有它的消费者才可以访问
         * 参数4： 是否自动删除，true表示不再使用队列时自动删除队列
         * 参数5：其他的额外参数
         * */
        channel.queueDeclare("SEND_MAIL",true,false,false,null);
        channel.queueDeclare("SEND_MESSAGE",true,false,false,null);
        channel.queueDeclare("SEND_STATION",true,false,false,null);
        //6.交换机绑定队列
        /**
         * 参数1：队列名
         * 参数2：交换机名
         * 参数3：路由关键字，发布订阅模式写""即可
         */
        channel.queueBind("SEND_MAIL","exchange_fanout","");
        channel.queueBind("SEND_MESSAGE","exchange_fanout","");
        channel.queueBind("SEND_STATION","exchange_fanout","");
        //7.发送信息
        /*
        * 参数1：交换机名
         * 参数2：路由关键字，发布订阅模式写""即可
         * 参数3：其他的额外参数
         * 参数4： 要传送的字节数组*/
        for(int i=1;i <= 10 ;i++){
            /*这里参数1：交换机名，而不是队列，交换机会将发送的消息分在三条队列中，每条队列都是10条信息*/
            channel.basicPublish("exchange_fanout","",null,
                    ("你好，尊敬的用户，秒杀商品开抢了！"+i).getBytes(StandardCharsets.UTF_8));
        }
        //8.关闭资源
        channel.close();
        connection.close();
    }
}
/*在开发过程中，有一些消息需要不同消费者进行不同的处理，如电商网站的同一条促销信息需要短信发送、邮件发送、站内信发送等。此时可以使用发布订阅模式(Publish/Subscribe)

特点：

生产者将消息发送给交换机，交换机将消息转发到绑定此交换机的每个队列中。
工作队列模式的交换机只能将消息发送给一个队列，发布订阅模式的交换机能将消息发送给多个队列。发布订阅模式使用fanout交换机。*/